using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace iWindows
{
  public class CommandWindow : TextBox
  {

    Process commandProc;

    delegate void WriteText(string inText );
    delegate bool KeepRunningThread();

    Thread consoleRead;
    Thread consoleWrite;

    StreamReader consoleOut;
    StreamWriter consoleIn;

    Form parentForm;

    public CommandWindow(Form parent)
      : base()
    {
      
      parentForm = parent;

      CreateCommandProcess();
      
      consoleRead = new Thread(new ThreadStart(StartReading));
      consoleRead.Start();

      parentForm.DoubleClick += new EventHandler(OnDoubleClick);
      parentForm.FormClosing += new FormClosingEventHandler(OnClosing);

      parentForm.KeyPress += new KeyPressEventHandler(OnKeyPress);
      KeyPress += new KeyPressEventHandler(OnKeyPress);

      ReadOnly = true;
    }

    void OnKeyPress(object sender, KeyPressEventArgs e)
    {
      char c = e.KeyChar;
      if (e.KeyChar == '\r')
      {
        WriteToTextBox("\n");
        c = '\n';
      }

      if (consoleIn != null)
      {
        consoleIn.Write(c);
      }
    }

    void OnClosing(object sender, FormClosingEventArgs e)
    {
      if (commandProc != null)
      {
        commandProc.Kill();
      }

      if (consoleRead != null)
      {
        consoleOut.Dispose();
        consoleRead.Abort();
      }
      if (consoleWrite != null)
      {
        consoleWrite.Abort();
      }
      consoleOut = null;
      consoleIn = null;
    }

    void OnDoubleClick(object sender, EventArgs e)
    {
      if (parentForm.FormBorderStyle == FormBorderStyle.Sizable)
      {
        parentForm.FormBorderStyle = FormBorderStyle.None;
      }
      else
      {
        parentForm.FormBorderStyle = FormBorderStyle.Sizable;
      }
    }

    bool KeepRunning()
    {
      bool retVal = false;
      if (consoleRead != null && consoleWrite != null)
      {
        retVal = consoleRead.IsAlive && consoleWrite.IsAlive;
      }
      return retVal;
    }

    void WriteToTextBox(string inText)
    {
      Text += inText;
    }

    private void StartReading()
    {
      try
      {
        while (consoleRead.ThreadState != System.Threading.ThreadState.Aborted)
        {
          char c = (char)consoleOut.Read();
          Invoke(new WriteText(WriteToTextBox), c.ToString());
        }
      }
      catch( Exception e )
      {
      }
    }

    private void StartWriting()
    {
    }

    protected void CreateCommandProcess()
    {
      try
      {
        commandProc = new Process();
        commandProc.StartInfo.FileName = "cmd.exe";
        commandProc.StartInfo.RedirectStandardOutput = true;
        commandProc.StartInfo.RedirectStandardInput = true;
        commandProc.StartInfo.UseShellExecute = false;
        commandProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        commandProc.StartInfo.CreateNoWindow = true;

        commandProc.Start();

        consoleIn = commandProc.StandardInput;
        consoleOut = commandProc.StandardOutput;
        
      }
      catch
      {
        this.Enabled = false;
      }
    }
  }
}
